package gotlib

import (
	"bytes"
	"encoding/json"
	"fmt"
	"io"
)

// RawMessage is a raw encoded JSON value. //Todo
// It implements Marshaler and Unmarshaler and can
// be used to delay JSON decoding or precompute a JSON encoding.
type RawMessage = json.RawMessage

// JsonMarshal adapts to json/encoding Marshal API.
//
// Marshal returns the JSON encoding of v, adapts to json/encoding Marshal API
// Refer to https://godoc.org/encoding/json#Marshal for more information.
func JsonMarshal(v interface{}) (marshaledBytes []byte, err error) {
	marshaledBytes, err = json.Marshal(v)
	if err != nil {
		err = ErrorAddInfo(err, `json.Marshal failed`)
	}
	return
}

func MarshalToString(v interface{}) (json string) {
	by, err := JsonMarshal(v)
	if err != nil {
		return ""
	}
	return String(by)
}

func UnMarshalToMap(jsonString string) (v map[string]interface{}) {
	v = make(map[string]interface{})
	err := json.Unmarshal(StringToBytes(jsonString), &v)
	if err != nil {
		fmt.Println("UnMarshalToMap Error:", err, jsonString)
		return nil
	}
	return v
}

// JsonMarshalIndent same as json.MarshalIndent.
func JsonMarshalIndent(v interface{}, prefix, indent string) (marshaledBytes []byte, err error) {
	marshaledBytes, err = json.MarshalIndent(v, prefix, indent)
	if err != nil {
		err = ErrorAddInfo(err, `json.MarshalIndent failed`)
	}
	return
}

// JsonUnmarshal adapts to json/encoding Unmarshal API
//
// Unmarshal parses the JSON-encoded data and stores the result in the value pointed to by v.
// Refer to https://godoc.org/encoding/json#Unmarshal for more information.
func JsonUnmarshal(data []byte, v interface{}) (err error) {
	err = json.Unmarshal(data, v)
	if err != nil {
		err = ErrorAddInfo(err, `json.Unmarshal failed`)
	}
	return
}

// JsonUnmarshalUseNumber decodes the json data bytes to target interface using number option.
func JsonUnmarshalUseNumber(data []byte, v interface{}) (err error) {
	decoder := JsonNewDecoder(bytes.NewReader(data))
	decoder.UseNumber()
	err = decoder.Decode(v)
	if err != nil {
		err = ErrorAddInfo(err, `json.UnmarshalUseNumber failed`)
	}
	return
}

// JsonNewEncoder same as json.NewEncoder
func JsonNewEncoder(writer io.Writer) *json.Encoder {
	return json.NewEncoder(writer)
}

// JsonNewDecoder adapts to json/stream NewDecoder API.
//
// NewDecoder returns a new decoder that reads from r.
//
// Instead of a json/encoding Decoder, a Decoder is returned
// Refer to https://godoc.org/encoding/json#NewDecoder for more information.
func JsonNewDecoder(reader io.Reader) *json.Decoder {
	return json.NewDecoder(reader)
}

// JsonValid reports whether data is a valid JSON encoding.
func JsonValid(data []byte) bool {
	return json.Valid(data)
}

// FormatJsonToMapStrStr 格式化Json字符串为MapStrStr格式
func FormatJsonToMapStrStr(jsonParams string) map[string]string {
	if jsonParams == "" {
		return nil
	}
	m := make(map[string]interface{})
	if err := json.Unmarshal([]byte(jsonParams), &m); err != nil {
		return nil
	}

	n := make(map[string]string)
	for k, v := range m {
		n[k] = String(v)
	}
	return n
}

// FormatJsonToArrayMapStrInterface 格式化Json字符串为[]MapStrStr格式
func FormatJsonToArrayMapStrInterface(jsonParams string) []map[string]Interface {
	if jsonParams == "" {
		return nil
	}
	var m []map[string]Interface

	if err := json.Unmarshal([]byte(jsonParams), &m); err != nil {
		return nil
	}

	//n := []map[string]string
	//for k, v := range m {
	//	n[k] = String(v)
	//}
	return m
}

// FormatJsonToMapStrInterface 格式化Json字符串为MapStrInterface格式
func FormatJsonToMapStrInterface(jsonParams string) (m map[string]interface{}) {
	m = make(map[string]interface{})
	if jsonParams == "" {
		return
	}

	if err := json.Unmarshal([]byte(jsonParams), &m); err != nil {
		return
	}

	return
}

// ReplaceInt64ItemInJsonString JsonString里面把其中的int数字替换掉
func ReplaceInt64ItemInJsonString(sourceJsonString string, from, to int64) (newJsonString string) {
	items := JsonToInt64s(sourceJsonString)

	iLen := len(items)
	for i := 0; i < iLen; i++ {
		if items[i] == from {
			items[i] = to
		}
	}
	json, _ := json.Marshal(items)
	return String(json)
}
